#include "SessinoFriendArea.h"
#include "Debug.h"
#include "model/data.h"
#include "mainwidget.h"
#include "model/datacenter.h"

SessinoFriendArea::SessinoFriendArea(QWidget *parent)
    : QScrollArea{parent}
{
    // ⼀定要添加这个设置, 否则⽆法正确显⽰.
    this->setWidgetResizable(true);
    verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 2px; background-color: rgb(233, 231, 230); }"
                                       " QScrollBar::handle:vertical {background-color: rgb(178, 178, 178);}");
    horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal {height: 0px;}");
    // horizontalScrollBar()->setVisible(false); // 设置这个不可见，下面会有一个空白区域
    setStyleSheet("QWidget{ border:none;}");    // 去边框

    m_container = new QWidget();
    m_container->setFixedWidth(200);
    setWidget(m_container);

    QVBoxLayout* layout = new QVBoxLayout();
    m_container->setLayout(layout);

    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    layout->setAlignment(Qt::AlignTop); // 顶部对齐

// 测试
#if TEST_UI
    QIcon* avatar = new QIcon(":/resource/image/defaultAvatar2.jpg");
    QString user = "用户";
    QString text = "最新消息";
    for (int i = 0; i < 15; ++i) {
        addItem(FRIENDITEMTYPE, QString::number(i+1), *avatar, user+QString::number(i), text);
    }
#endif
}

void SessinoFriendArea::addItem(ITEMTYPE itemType, const QString& id, const QIcon &avatar, const QString &name, const QString &text)
{
    SessionFriendItem* item;
    if(itemType == SESSIONITEMTYPE){
        item = new SessionItem(this, id, avatar, name, text);
    }else if(itemType == FRIENDITEMTYPE){
        item = new FriendItem(this, id, avatar, name, text);
    }else if(itemType == APPLYITEMTYPE){
        item = new ApplyItem(this, id, avatar, name);
    }else{
        item = nullptr;
        LOG() << "生成的对象类型未知";
        return ;
    }

    m_container->layout()->addWidget(item);
}

void SessinoFriendArea::clear()
{
    QLayout* layout = m_container->layout();
    // for (int i = layout->count(); i >= 0; --i) {
    //     QLayoutItem* item = layout->takeAt(i);
    //     if(item){
    //         delete item->widget();
    //         delete item;
    //     }
    // }

    // 官方写法
    QLayoutItem *child;
    while ((child = layout->takeAt(0)) != nullptr) {
        delete child->widget(); // delete the widget
        delete child;   // delete the layout item
    }
}

void SessinoFriendArea::clickItem(int index)
{
    if (index >= m_container->layout()->count()) {
        qCritical() << TAG << "点击的元素下标超出范围! index=" << index;
        return;
    }
    QLayoutItem* top = m_container->layout()->itemAt(index);
    if (top->widget() == nullptr) {
        qCritical() << TAG << "指定元素不存在! index=" << index;
        return;
    }
    SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(top->widget());
    item->select();
    item->active();
}

SessionFriendItem::SessionFriendItem(QWidget *owner, const QIcon &avatar, const QString &name, const QString &text)
    :m_owner(owner), m_isSelect(false)
{
    setFixedHeight(70);
    setStyleSheet("QWidget{ background-color: rgb(233, 231, 230);}");

    QGridLayout* layout = new QGridLayout();
    setLayout(layout);
    layout->setContentsMargins(10, 0, 0, 0);
    layout->setHorizontalSpacing(10); // 水平间距为10
    layout->setVerticalSpacing(0);    // 垂直间距为0

    // 创建头像
    QPushButton* userBtn = new QPushButton();
    userBtn->setFixedSize(50, 50);
    userBtn->setIconSize(QSize(50, 50));
    userBtn->setIcon(avatar);
    userBtn->setStyleSheet("QPushButton {background-color: rgb(231, 230, 229);}");
    userBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // Fixed固定大小，Expanding尽可能的占据空间

    // 创建昵称
    QLabel* nameLabel = new QLabel(name);
    nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    nameLabel->setAlignment(Qt::AlignBottom); // 调整下⽂字对⻬位置, 看起来更好看⼀些.
    nameLabel->setFixedHeight(35);
    nameLabel->setStyleSheet("QLabel {font-size: 16px;}"); // 字体调大

    // 最新的消息
    m_textLabel = new QLabel(text);
    m_textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    m_textLabel->setFixedHeight(35);
    m_textLabel->setStyleSheet("QLabel {color: rgb(153, 153, 153);}"); // 字体颜色

    // 一列两行
    layout->addWidget(userBtn, 0, 0, 2, 1);
    layout->addWidget(nameLabel, 0, 1, 1, 8);
    layout->addWidget(m_textLabel, 1, 1, 1, 8);
}

void SessionFriendItem::select()
{
    QObjectList children = this->parentWidget()->children();
    for(QObject* child : children){
        if(!child->isWidgetType())
            continue;
        SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(child);
        if(item){
            item->m_isSelect = false;
            item->setStyleSheet("QWidget{ background-color: rgb(233, 231, 230);}");
        }
    }
    m_isSelect = true;
    setStyleSheet("QWidget{ background-color: rgb(196, 196, 196);}");
}

void SessionFriendItem::paintEvent(QPaintEvent *)
{
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

void SessionFriendItem::mousePressEvent(QMouseEvent *event)
{

}

void SessionFriendItem::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton){
        select();
        active();   // 调用相对应的窗口
    }else if(event->button() == Qt::RightButton){
        // TODO:
    }
}

void SessionFriendItem::enterEvent(QEnterEvent *)
{
    if(m_isSelect)
        return;
    setStyleSheet("QWidget{ background-color: rgb(217, 216, 216)}");
}


void SessionFriendItem::leaveEvent(QEvent *)
{
    if(m_isSelect)
        return;
    setStyleSheet("QWidget{ background-color: rgb(233, 231, 230);}");
}

////////////////////////////////////
///         会话item
////////////////////////////////////
SessionItem::SessionItem(QWidget *owner, const QString &chatSessionId, const QIcon &avatar,
                        const QString &name, const QString &lastMessage)
    :SessionFriendItem(owner, avatar, name, lastMessage), m_chatSessionId(chatSessionId)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::updateLastMessage, this, &SessionItem::updateLastMessage);

    int unRead = dataCenter->getUnreadMsg(chatSessionId);
    if(unRead > 0){
        m_textLabel->setText(QString("[%1]条 ").arg(dataCenter->getUnreadMsg(chatSessionId)) + lastMessage);
    }
}

void SessionItem::active()
{
    LOG()<<"会话界面调用";
    // 加载会话历史消息，会涉及到 1.当前内存的数据操作，2.网络通信，3.界面的更变
    MainWidget* window = MainWidget::getInstance();
    window->loadRecentMessages(m_chatSessionId);
    // 清空未读消息，并实时更新显示
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    dataCenter->clearUnreadMsg(m_chatSessionId);

    auto recentMsgList = dataCenter->getRecentMsgList(m_chatSessionId);
    if(recentMsgList){
        // 这里做的原因是传输的可能是图片，音频，文件消息，这样就不能使用 m_content 的内容了，因为都是二进制数据
        QString text = m_textLabel->text();
        static QRegularExpression reg(R"(\[\S+\]条)");
        m_textLabel->setText(text.replace(reg, ""));
    }
}

void SessionItem::updateLastMessage(const QString &chatSessionId)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    if(m_chatSessionId != chatSessionId){
        return ;
    }

    // 拿到当前会话的最新消息列表的最新一条（也就是最后一条）
    const QList<Message>* recentMsgList = dataCenter->getRecentMsgList(chatSessionId);
    if (recentMsgList == nullptr || recentMsgList->size() == 0) {
        return;
    }

    // 根据不同情况设置不同的最新消息
    const Message& lastmsg = recentMsgList->back();
    QString text = lastmsg.m_content;
    LOG() << "更新消息内容长度为：" << lastmsg.m_content.length() << "|" << text.length();
    if(lastmsg.m_type == MessageType::TEXT_TYPE){
        text = lastmsg.m_content;
    }else if(lastmsg.m_type == MessageType::IMAGE_TYPE){
        text = "[图片]";
    }else if(lastmsg.m_type == MessageType::FILE_TYPE){
        text = "[文件] " + lastmsg.m_fileName;
    }else if(lastmsg.m_type == MessageType::SPEECH_TYPE){
        text = "[语音]";
    }else{
        text = "未知消息类型";
        LOG() << "消息类型错误";
    }

    // 不相同就是未读消息
    if(dataCenter->getCurrentChatSessionId() != chatSessionId){
        m_textLabel->setText(QString("[%1]条 ").arg(dataCenter->getUnreadMsg(chatSessionId)) + text);
    }else{
        m_textLabel->setText(text);
    }
}

FriendItem::FriendItem(QWidget *owner, const QString &userId, const QIcon &avatar,
                       const QString &name, const QString &description)
    :SessionFriendItem(owner, avatar, name, description), m_userId(userId){}

void FriendItem::active()
{
    LOG()<<"好友界面调用";
    MainWidget* window = MainWidget::getInstance();
    window->switchToSession(m_userId);
}

ApplyItem::ApplyItem(QWidget *owner, const QString &userId, const QIcon &avatar, const QString &name)
    :SessionFriendItem(owner, avatar, name, ""), m_userId(userId)
{
    QGridLayout* layout = dynamic_cast<QGridLayout*>(this->layout());
    // 1. 删除最后一个组件
    // QWidget* widget = dynamic_cast<QWidget*>(layout->itemAtPosition(1, 1));
    layout->removeWidget(m_textLabel);
    // delete m_textLabel;
    m_textLabel->deleteLater();

    // 2. 创建两个按钮
    QPushButton* acceptBtn = new QPushButton("同意");
    QPushButton* rejectBtn = new QPushButton("拒绝");

    layout->addWidget(acceptBtn, 1, 1);
    layout->addWidget(rejectBtn, 1, 2);

    // 3. 绑定信号
    connect(acceptBtn, &QPushButton::clicked, this, [=]{
        // 同意好友申请
        model::DataCenter* dataCenter = model::DataCenter::getInstance();
        dataCenter->acceptFriendApplyAsync(m_userId);
    });
}

void ApplyItem::active()
{
    LOG()<<"申请界面调用";
}
